package com.smile.cloud.admin.filter;

import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.json.JSONUtil;
import com.smile.cloud.common.base.result.CommonResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Method;
import java.nio.charset.StandardCharsets;

import static com.smile.cloud.common.base.result.BaseResultEnum.UNAUTHORIZED;


/**
 * 认证拦截器
 *
 * @author LGC
 * @date 2021/8/2 14:20
 * @copyright 2021 mofang. All rights reserved
 */
@Slf4j
public class AuthInterceptor implements HandlerInterceptor {

    @Resource
    private IJwtTokenService jwtTokenService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        log.info("====拦截到了方法：{}，在该方法执行之前执行====", request.getServletPath());
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        Method method = handlerMethod.getMethod();
        // 不需要认证直接跳过拦截
        UnAuthInterceptor unAuthInterceptor = method.getAnnotation(UnAuthInterceptor.class);
        if (unAuthInterceptor != null) {
            return true;
        }
        // 判断用户有没有登陆，对应的token
        String token = request.getHeader("token");
        if (!StrUtil.isNotBlank(token)) {
            log.info("header without token");
            unAuthenticationEntryPoint(response);
            return false;
        }
        try {
            PayloadDto payloadDto = jwtTokenService.verifyTokenByHMAC(token, SecureUtil.md5("ssa-analyse"));
            if (payloadDto == null) {
                log.info("toke verify fail, payload is null");
                unAuthenticationEntryPoint(response);
                return false;
            }
            log.info("payload:{}", payloadDto);
        } catch (Exception e) {
            log.error("verify token error:{}", e.getMessage());
            unAuthenticationEntryPoint(response);
            return false;
        }

        // 返回true才会继续执行，返回false则取消当前请求
        return true;
    }


    private void unAuthenticationEntryPoint(HttpServletResponse response) throws IOException {
        response.setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, "*");
        response.setHeader(HttpHeaders.CACHE_CONTROL, "no-cache");
        response.setCharacterEncoding(String.valueOf(StandardCharsets.UTF_8));
        response.setContentType(MediaType.APPLICATION_JSON_VALUE);
        response.getWriter().println(JSONUtil.parse(CommonResult.failed(UNAUTHORIZED)));
        response.getWriter().flush();
    }
}